from django.db import transaction
from django.shortcuts import render
from django.utils import timezone
from django.shortcuts import redirect
from rest_framework import viewsets
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework import mixins

from trade.models import ShoppingCart, OrderInfo, OrderGoods
from utils.alipay import AliPay
from utils.perssions import IsOwnerOrReadOnly
from .serializer import ShoppingCartSerializer, ShoppingCartDetailSerializer, \
    OrderSerializer, OrderDetailSerializer
from rest_framework.views import APIView


# Create your views here.

class ShoppingCartViewSet(viewsets.ModelViewSet):
    """
    购物车功能
    list:
        购物车列表
    create:
        添加购物车
    delete:
        删除购物车商品
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JWTAuthentication, SessionAuthentication)
    serializer_class = ShoppingCartSerializer
    lookup_field = 'goods_id'

    def get_queryset(self):
        return ShoppingCart.objects.filter(user=self.request.user)

    def get_serializer_class(self):
        if self.action == 'list':
            return ShoppingCartDetailSerializer
        else:
            return ShoppingCartSerializer

    # 添加商品到购物车，商品库存要减去添加数
    def perform_create(self, serializer):
        shop_cart = serializer.save()
        goods = shop_cart.goods
        goods.goods_num -= shop_cart.nums
        goods.save()

    # 删除购物车商品，商品库存要加上删除数
    def perform_destroy(self, instance):
        goods = instance.goods
        goods.goods_num += instance.nums
        goods.save()
        instance.delete()

    # 更新购物车商品，商品库存要减去更新数/加上更新数
    def perform_update(self, serializer):
        existed = ShoppingCart.objects.get(id=serializer.instance.id)
        existed_nums = existed.nums
        saved_record = serializer.save()
        nums = saved_record.nums - existed_nums
        goods = saved_record.goods
        if nums > 0:
            goods.goods_num -= nums
            goods.save()
        else:
            goods.goods_num += nums
            goods.save()


class OrderViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, mixins.RetrieveModelMixin,
                   mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
    订单管理
    list:
        订单列表
    create:
        创建订单
    delete:
        删除订单
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JWTAuthentication, SessionAuthentication)
    # serializer_class = OrderSerializer

    def get_queryset(self):
        return OrderInfo.objects.filter(user=self.request.user)

    def get_serializer_class(self):
        if self.action == 'retrieve':
            return OrderDetailSerializer
        return OrderSerializer

    def perform_create(self, serializer):
        order = serializer.save()
        shopping_carts = ShoppingCart.objects.filter(user=self.request.user)
        for shopping_cart in shopping_carts:
            order_goods = OrderGoods()
            order_goods.order = order
            order_goods.goods = shopping_cart.goods
            order_goods.save()
            shopping_cart.delete()
        return order

class AlipayView(APIView):
    def get(self, request):
        '''
        处理支付宝的return_url
        '''
        processed_dict = {}
        for key, value in request.GET.items:
            processed_dict[key] = value
        sign = processed_dict.pop("sign", None)

        alipay = AliPay()
        verify_result = alipay.verify(processed_dict, sign)
        if verify_result is False:
            response = redirect('index')
            response.set_cookie('nextPath', 'pay', max_age=2)
            return response
        else:
            order_sn = processed_dict.get("out_trade_no", None)
            trade_no = processed_dict.get("trade_no", None)
            trade_status = processed_dict.get("trade_status", None)
            existed_orders = OrderInfo.objects.filter(order_sn=order_sn)
            for existed_order in existed_orders:
                # 支付成功，商品的销量要加上
                order_goods = existed_order.goods.all()
                for order_good in order_goods:
                    goods = order_good.goods
                    goods.sold_num += order_good.goods_num
                    goods.save()

                existed_order.pay_status = trade_status
                existed_order.trade_no = trade_no
                existed_order.pay_time = timezone.now()
                existed_order.save()

            # return Response("success")
            response = redirect('index')
            response.set_cookie('nextPath', 'pay', max_age=2)
            return response


    def post(self, request):
        '''
        处理支付宝的notify_url
        '''
        processed_dict = {}
        for key, value in request.POST.items:
            processed_dict[key] = value
        sign = processed_dict.pop("sign", None)

        alipay = AliPay()
        verify_result = alipay.verify(processed_dict, sign)
        if verify_result is True:
            order_sn = processed_dict.get("out_trade_no", None)
            trade_no = processed_dict.get("trade_no", None)
            trade_status = processed_dict.get("trade_status", None)
            existed_orders = OrderInfo.objects.filter(order_sn=order_sn)
            for existed_order in existed_orders:
                # 支付成功，商品的销量要加上
                order_goods = existed_order.goods.select_for_update()
                with transaction.atomic():
                    for order_good in order_goods:
                        goods = order_good.goods
                        goods.sold_num += order_good.goods_num
                        goods.save()

                existed_order.pay_status = trade_status
                existed_order.trade_no = trade_no
                existed_order.pay_time = timezone.now()
                existed_order.save()

            return Response("success")